Raspberry PiとAWS IoTでLチカしてみた
Raspberry Pi(ラズベリーパイ)とAWS IoTでLチカしてみたいと思います。AWS IoTでシャドウ(Thing Shadow)を更新すると、MQTTで接続しているRaspberry Piが差分を受け取り、LEDをON/OFFする仕組みを構築します。
環境情報
次のようなMacbookとRaspberry Piの環境で開発しています。また、Raspberry Piをリモートから操作するため、MacbookからRaspberry PiにVNCとSSHで接続できるようにしています。
Macbook
項目 | 内容 |
---|---|
モデル | MacBook Pro (13-inch, 2018, Four Thunderbolt 3 Ports) |
OS | macOS Catalina 10.15.4(19E287) |
プロセッサ | 2.3 GHz クアッドコアIntel Core i5 |
メモリ | 16 GB 2133 MHz LPDDR3 |
Raspberry Pi
項目 | 内容 |
---|---|
モデル | Raspberry Pi 4 Model B |
OS | Raspbian 10 (Raspbian GNU/Linux 10 buster) |
SDカード | SanDisk Ultra microSDHC 32GB SDSQUAR-032G-GN6MN |
電源 | 電源アダプター USB Type-C 5.1V/3A |
その他(部品)
- ブレッドボード ×1
- ジャンパーワイヤー(オス-メス) ×2
- LED ×1
- 抵抗器 1KΩ ×1
Raspberry PiだけでLチカ
まずは、Raspberry PiだけでLチカできることを確認します。後ほど「AWS IoT Device SDK for JavaScript」を使用したいので、Node.jsで開発することにします。
配線
次の画像のようにRaspberry Piからブレッドボードへ配線します。
Node.jsをインストール
Raspberry Piに最新のNode.jsとnpmをインストールします。Raspberry Piのターミナルを使用するかSSHで接続して作業します。
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
Nodeとnpmをインストールします。
sudo apt-get install -y nodejs
インストールされたNodeとnpmのバージョンを確認します。
node -v # v12.16.2 npm -v # 6.14.4
Lチカ用のコードを実装
プロジェクト用のディレクトリを用意して、GPIOの操作で使用するライブラリをインストールします。
mkdir raspberry-pi-sample cd raspberry-pi-sample npm init npm install rpi-gpio --save
1秒毎に8番ピンをON/OFFするコードを実装します。
const gpio = require("rpi-gpio"); const PIN = 8; // 8番ピン(GPIO14) let LED = true; gpio.setup(PIN, gpio.DIR_OUT, () => { setInterval(() => { if (LED) { gpio.write(PIN, false); LED = false; } else { gpio.write(PIN, true); LED = true; } }, 1000); });
Lチカしてみる
Raspberry Pi上でコードを実行します。
node main.js
LEDが1秒毎に点灯と消灯を繰り返します。
Raspberry PiとAWS IoTでLチカ
今度はRaspberry PiとAWS IoTをMQTTで接続して、サブスクリプション要求により受け取る差分を処理して、LEDをON/OFFしてみます。まずは、AWS IoTに接続するための準備から始めます。
AWS IoTでポリシーを作成
AWS IoT Coreのマネジメントコーンソールからポリシーを作成します。
適当なポリシー名を入力します。アクションにiot:*
リソースに*
に入力、効果は許可
にチェックをしてポリシー作成します。
AWS IoTでモノを作成
AWS IoT Coreのマネジメントコーンソールから単一のモノを作成します。
適当なモノの名前を入力して次へ進みます。
AWS IoTで証明書を作成
モノに証明書を追加します。次の画面が表示されるので「1-Click 証明書作成 (推奨)」で証明書を作成します。
証明書の作成が完了したら、次の画面で証明書や秘密鍵をダウンロードします。また、証明書を有効化して先ほど作成したポリシーをアタッチしておきます。
AWS IoTのエンドポイントを取得
AWS IoT CoreのマネジメントコンソールからAWS IoT Coreへ接続するためのエンドポイントを取得します。
AWS IoT Device SDK for JavaScriptをインストール
npmでAWS IoT Device SDK for JavaScriptをインストールします。
npm install aws-iot-device-sdk --save
Lチカ用のコードを実装
サブスクリプション要求により受け取る差分を処理して、LEDをON/OFFするコードを実装します。秘密鍵や証明書のパスはあらかじめダウンロードしたファイルのパスを設定します。raspberry-pi-sample
はモノを作成した際の名前に変更してください。
const awsIot = require("aws-iot-device-sdk"); const gpio = require("rpi-gpio"); const PIN = 8; // 8番ピン(GPIO14) const device = awsIot.device({ keyPath: "xxxxxxxxx-private.pem.key", // 秘密鍵 certPath: "xxxxxxxxx-certificate.pem.crt", // 証明書 caPath: "amazon-root-ca1.pem", // CA証明書 clientId: "raspberry-pi-sample", // ClientID host: "xxxxxxxxxxxxxx-ats.iot.ap-northeast-1.amazonaws.com", // エンドポイント }); device.on("connect", function () { console.log("connect"); device.subscribe("$aws/things/raspberry-pi-sample/shadow/update/delta"); device.publish( "$aws/things/raspberry-pi-sample/shadow/update", JSON.stringify({ state: { reported: { led: "off", }, }, }) ); gpio.setup(PIN, gpio.DIR_OUT, () => { gpio.write(PIN, true); // true=消灯 }); }); device.on("message", function (topic, payload) { console.log("message", topic, payload.toString()); const shadow = JSON.parse(payload.toString()); if (shadow.state && shadow.state.led) { console.log("led", shadow.state.led); const led = shadow.state.led !== "on"; gpio.setup(PIN, gpio.DIR_OUT, () => { gpio.write(PIN, led); }); device.publish( "$aws/things/raspberry-pi-sample/shadow/update", JSON.stringify({ state: { reported: { led: shadow.state.led, }, }, }) ); } });
MQTTのトピックはAWS IoTの予約されたトピックを使用しています。
Lチカしてみる
Raspberry Pi上でコードを実行します。
node main.js
AWS IoTでシャドウを確認します。
desired
に"led": "on"
を書き込んで保存します。
{ "desired": { "led": "on" }, "reported": { "led": "off" } }
保存するとdelta
に差分が追加されます。
{ "desired": { "led": "on" }, "reported": { "led": "off" }, "delta": { "led": "on" } }
Raspberry Piで差分を処理してreported
が更新されます。
{ "desired": { "led": "on" }, "reported": { "led": "on" } }
処理が終わるとLEDが点灯します。
desired
に"led": "off"
を書き込んで保存します。
{ "desired": { "led": "off" }, "reported": { "led": "on" } }
LEDが消灯します。
まとめ
Raspberry PiとAWS IoTでLチカすることができました。API Gatewayから実行するLambdaでシャドウのdesired
を更新することで、WEBアプリからLEDをON/OFFすることもできそうです。他にもRaspberry Piにスイッチを接続して、LEDのON/OFFを制御するケースも考えられると思います。